
import com.wider.foundation.concurrency.MultiBuffer;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author William Choi
 */
public class FileTest {
    public static void main (String args[]) throws IOException, InterruptedException{
        /*
        File fileD = new File("D:");
        File file1 = new File(fileD, "VAs/Sexy Copy");
        System.out.println(fileD.toString());
        System.out.println(file1.toString());
        System.out.println(file1.exists());
        System.out.println(file1.getAbsoluteFile());
        System.out.println(file1.getAbsolutePath());
        System.out.println(file1.getCanonicalFile());
        System.out.println(file1.getCanonicalPath());
        System.out.println(file1.getName());
        System.out.println(file1.getParent());
        System.out.println(file1.getParentFile());
        System.out.println(file1.getPath());

        File file2 = (File) new NxFile(new HttpChannel("test"), fileD, "Jworkspace");
        System.out.println(file2.exists());
        */


        /*
        final File file_src = new File("G:/VAs/2010_03", "1GAR00104.wmv");
        File file_ds1 = new File("e:/temp", "test-1_" + file_src.getName());
        File file_ds2 = new File("e:/temp", "test-2_" + file_src.getName());
        File file_ds3 = new File("e:/temp", "test-3_" + file_src.getName());

        final FileInputStream fis     = new FileInputStream(file_src);
        FileOutputStream fo1    = new FileOutputStream(file_ds1);
        FileOutputStream fo2    = new FileOutputStream(file_ds2);
        final FileOutputStream fo3    = new FileOutputStream(file_ds3);

        DLoggerRoot rootlog = DLogger.getRoot();
        rootlog.setStream(System.out);
        rootlog.setLevel(DLogger.DLevel.DEBUG);
        rootlog.enable();


        //Test-1, FIS-->user buffer(8K)-->FOS
        byte[] buffer = new byte[4*1024];
        rootlog.debug("Start FAST-COPY-1");
        while(true){
            if (fis.read(buffer) == -1)
                break;
            fo1.write(buffer);
        }
        rootlog.debug("Done FAST-COPY-1");


        //Test-2, FIS-->BuffStream-->user buffer(8K)-->BuffStream-->FOS
        fis.close();
        fis     = new FileInputStream(file_src);
        BufferedInputStream bis  = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fo2);
        rootlog.debug("Start FAST-COPY-2");
        while(true){
            if (bis.read(buffer) == -1)
                break;
            bos.write(buffer);
        }
        rootlog.debug("Done FAST-COPY-2");


        //Test-3, FIS-->Channel-->FOS
        fis.close();
        fis     = new FileInputStream(file_src);
        rootlog.debug("Start FAST-COPY-3");
        FileChannel fcs = fis.getChannel();
        FileChannel fco = fo3.getChannel();
        fcs.transferTo(0, file_src.length(), fco);
        rootlog.debug("Start FAST-COPY-3");

        //Test-4, two-stage pipeline: seperating R/W

        Runnable RunnableRead = new Runnable(){
            @Override
            public void run() {
                while(true){
                    buff = new byte[8192];
                    if (fis.read(buffer) == -1)
                        break;
                }
            }
        };


        Thread.sleep(6000);

        
        final BlockingRingBuffer buffers = new BlockingRingBuffer(16, 8*1024); //best: 16 : 8K : 49sec for 1.86GB

        Runnable RunnableRead = new Runnable(){
            @Override
            public void run() {
                byte[] buf;
                while(true){
                    try {
                        buf = buffers.reserveForWrite();
                        if (fis.read(buf) < 0) {
                            buffers.releaseFromRead(buf);
                            break;
                        }
                        buffers.releaseFromWrite(buf);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(FileTest.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex) {
                        Logger.getLogger(FileTest.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }

            }
        };

        Runnable RunnableWrite = new Runnable(){
            @Override
            public void run() {
                byte[] buf;
                long size = 0;
                while(size < file_src.length()){
                    try {
                        buf = buffers.reserveForRead();
                        size += buf.length;
                        fo3.write(buf);
                        buffers.releaseFromRead(buf);
                    } catch (IOException ex) {
                        Logger.getLogger(FileTest.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(FileTest.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        };

        Thread thwr = new Thread(RunnableWrite);
        Thread thrd = new Thread(RunnableRead);

        thwr.setName("ThreadWr");
        thrd.setName("ThreadRd");

        
        thwr.start();
        rootlog.debug("Started...");
        thrd.start();

        try {
            thrd.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(FileTest.class.getName()).log(Level.SEVERE, null, ex);
        }

        rootlog.debug("Rd joined back");
        try {
            thwr.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(FileTest.class.getName()).log(Level.SEVERE, null, ex);
        }
        rootlog.debug("Wr joined back");
        
        fis.close();
        fo1.close();
        fo2.close();
        fo3.close();
        */

        /*
        Map<Object, Object> amap = new HashMap();
        amap.put("count", 100);
        amap.put("name", "kiki");

        for (Map.Entry e : amap.entrySet()){
            System.out.println(e.getKey() + ": " + e.getValue().toString());
        }
        */


        /*
        MultiBuffer mbuff = new MultiBuffer(3, 4);

        List buff1 = mbuff.getBuffer();
        mbuff.lockBuffer(buff1);

        List buff2 = mbuff.getBuffer();
        mbuff.lockBuffer(buff2);

        List buff3 = mbuff.getBuffer();
        mbuff.lockBuffer(buff3);

        buff1.add("buff-1");
        buff2.add("buff-2");
        buff3.add("buff-3");

        mbuff.releaseBuffer(buff2);
        mbuff.releaseBuffer(buff3);
        mbuff.releaseBuffer(buff1);

        buff1 = mbuff.getBuffer();
        mbuff.lockBuffer(buff1);

        buff2 = mbuff.getBuffer();
        mbuff.lockBuffer(buff2);

        buff3 = mbuff.getBuffer();
        mbuff.lockBuffer(buff3);

        System.out.println("--> " + buff1.get(0));
        System.out.println("--> " + buff2.get(0));
        System.out.println("--> " + buff3.get(0));
         *
         */

        System.out.println("BufferedPrint Test");
        BufferedPrint bprinter = new BufferedPrint();
        bprinter.printf("Hello yoyo");
        bprinter.printf("Hello yoyo");
        Thread.sleep(2000);
        bprinter.printf("I Love KiKi");
        Thread.sleep(500);
        bprinter.printf("I Love KiKi");
        bprinter.printf("I Love KiKi");
        bprinter.printf("I Love KiKi");
        Thread.sleep(3000);
        bprinter.shutdown();
    }
}
